package com.higgins.client.components;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;
import com.higgins.client.GreetingService;
import com.higgins.client.GreetingServiceAsync;
import com.higgins.client.dataModel.CoveringLetterDTO;
import com.higgins.client.dataModel.LawFirmDTO;
import com.higgins.client.dataModel.LawFirmTypeDTO;
import com.higgins.client.dataModel.RecipientCountDTO;
import com.higgins.client.dataModel.RegionDTO;
import com.higgins.client.dataModel.SectorDTO;
import com.higgins.client.dataModel.StatusDTO;
import com.higgins.client.dataModel.StrategyDTO;
import com.higgins.client.generic.components.GenericColumn;
import com.higgins.client.generic.components.GenericTable;

public class LawFirmTable extends GenericTable	{
	private static final Logger log = Logger.getLogger(LawFirmTable.class.getName());
	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);
	private SectorDTO sectorDTO = null;
	private LawFirmTypeDTO lawFirmTypeDTO = null;
	
	public LawFirmTable(LawFirmColumns columns)	{
		super(columns);
		retrieveDTOs();
	}
   public void update(SectorDTO sectorDTO, LawFirmTypeDTO lawFirmTypeDTO)   {
        this.sectorDTO = sectorDTO;
        this.lawFirmTypeDTO = lawFirmTypeDTO;
        refresh();
    }

   protected void addObject(int row, int column, Object object)    {
        ensureRowAvailable(row);
        GenericColumn genericColumn = genericColumns.getColumn(column);
        if (genericColumn.getType().equals(SectorDTO.class))    {
            addSectorDTO(row, column, object, genericColumn);
        } else if (genericColumn.getType().equals(LawFirmTypeDTO.class))    {
            addLawFirmTypeDTO(row, column, object, genericColumn);
        } 

    }

   protected void addSectorDTO(int row, int column, Object object, GenericColumn genericColumn)    {
       final ListBox listBox = new ListBox();
       final int finalRow = row; 
       int count = 1;
       listBox.addItem("");
       List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
       for (Object listItem:(list!=null?list:new ArrayList<Object>())) {
           String item = ((SectorDTO)listItem).getName();
           listBox.addItem(item);
           if (((String)object).equals(item))  {
               listBox.setSelectedIndex(count);
           }
           count++;
       }
       listBox.addChangeHandler(new ChangeHandler() {
           public void onChange(ChangeEvent changeEvent) {
               SelectElement selectElement = listBox.getElement().cast();
               selectElement.getOptions().getItem(0).setDisabled(true);
               updateItemCell(finalRow);

           }
       });
       setWidget(row, column, listBox);
       getCellFormatter().addStyleName(row, column, "FlexTable-normCell");     
   }
   
   protected void addLawFirmTypeDTO(int row, int column, Object object, GenericColumn genericColumn)    {
       final ListBox listBox = new ListBox();
       final int finalRow = row; 
       int count = 1;
       listBox.addItem("");
       List<Object> list = genericColumn!=null?genericColumn.getList():new ArrayList<Object>();
       for (Object listItem:(list!=null?list:new ArrayList<Object>())) {
           String item = ((LawFirmTypeDTO)listItem).getName();
           listBox.addItem(item);
           if (((String)object).equals(item))  {
               listBox.setSelectedIndex(count);
           }
           count++;
       }
       listBox.addChangeHandler(new ChangeHandler() {
           public void onChange(ChangeEvent changeEvent) {
               SelectElement selectElement = listBox.getElement().cast();
               selectElement.getOptions().getItem(0).setDisabled(true);
               updateItemCell(finalRow);

           }
       });
       setWidget(row, column, listBox);
       getCellFormatter().addStyleName(row, column, "FlexTable-normCell");     
   }
	
	private List<List<Object>> convertDTOtoRowArray(List<LawFirmDTO> lawFirmDTOs)	{
		List<List<Object>> rows = new ArrayList<List<Object>>();
		for (LawFirmDTO lawFirmDTO:lawFirmDTOs)	{
			List<Object> row = new ArrayList<Object>();
			row.add(lawFirmDTO.getId());
            row.add(lawFirmDTO.getName());
            row.add(getSector(lawFirmDTO));
            row.add(getLawFirmType(lawFirmDTO));
            row.add(lawFirmDTO.getTurnover());
            row.add(lawFirmDTO.getNoSolicitors());
            row.add(lawFirmDTO.getNoOffices());
			row.add(lawFirmDTO.getAddress());
			rows.add(row);
		}
		return rows;
	}
	
	private String getSector(LawFirmDTO lawFirmDTO)   {
	    SectorDTO sector = getSectorDTO(lawFirmDTO.getSectorId());
	    if (sector!=null)  {
	        return sector.getName();
	    }
	    return "";
	}

    private String getLawFirmType(LawFirmDTO lawFirmDTO)   {
        LawFirmTypeDTO lawFirmTypeDTO = getLawFirmTypeDTO(lawFirmDTO.getLawFirmTypeId());
        if (lawFirmTypeDTO!=null)  {
            return lawFirmTypeDTO.getName();
        }
        return "";
    }
	
	public void updateItemCell(int row)	{
		LawFirmDTO lawFirmDTO = new LawFirmDTO();
		lawFirmDTO.setId(getId(row));
		lawFirmDTO.setName(getText(row, 1));
		lawFirmDTO.setSectorId(getSectorID(row, 2));
		lawFirmDTO.setLawFirmTypeId(getLawFirmTypeID(row, 3));
        lawFirmDTO.setTurnover(getDouble(row, 4));
        lawFirmDTO.setNoSolicitors(getInteger(row, 5));
        lawFirmDTO.setNoOffices(getInteger(row, 6));
        lawFirmDTO.setAddress(getText(row, 7));
		updateRow(lawFirmDTO);
	}
	
	protected void retrieveDTOs()	{
		try {
			greetingService.retrieveLawFirms( sectorDTO, lawFirmTypeDTO, new AsyncCallback<List<LawFirmDTO>>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("CoveringLetterDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(List<LawFirmDTO> results) {
						loadData(convertDTOtoRowArray(results));
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("CoveringLetterDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} */
	}	
	private void updateRow(LawFirmDTO lawFirmDTO)	{
		try {
			greetingService.updateLawFirm(lawFirmDTO, new AsyncCallback<String>()	{
					@Override
					public void onFailure(Throwable caught) {
						log.info("LawFirmDTO: " + caught.toString());
					}

					@Override
					public void onSuccess(String result) {
						setRowIdAfterUpdate(result);
					}
				});
		} catch (IllegalArgumentException e) {
			log.info("LawFirmDTO: " + e.toString());
		} /*catch (SecurityAccessDeniedException e) {
			log.info("SecurityAccessDeniedException: " + e.toString());
		} 		*/
	}
	
	public Long getSectorID(int row, int column)   {
	    SectorDTO dto = getSectorDTO(row, column);
	    if (dto!=null) {
	        return dto.getId();
	    }
	    return null;
	}
	
    public Long getLawFirmTypeID(int row, int column)   {
        LawFirmTypeDTO dto = getLawFirmTypeDTO(row, column);
        if (dto!=null) {
            return dto.getId();
        }
        return null;
    }
	
    public SectorDTO getSectorDTO(int row, int column)  {
        try {
            ListBox listBox = (ListBox)getWidget(row, column);
            int selectedIndex = listBox.getSelectedIndex();
            String sector = listBox.getItemText(selectedIndex);
            return getSectorDTO(sector);
        } catch (Exception e)   {
            return null;
        }
    }	
    
    @SuppressWarnings("unchecked")
    public SectorDTO getSectorDTO(String string)    {
        for (GenericColumn genericColumn:genericColumns.getColumns())   {
            if (genericColumn.getType()==(SectorDTO.class)) {
                if (genericColumn.getList()!=null)  {
                    for (SectorDTO dto:(List<SectorDTO>)genericColumn.getList())    {
                        if (dto.getName().equals(string))   {
                            return dto;
                        }
                    }
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public SectorDTO getSectorDTO(Long id)    {
        for (GenericColumn genericColumn:genericColumns.getColumns())   {
            if (genericColumn.getType()==(SectorDTO.class)) {
                if (genericColumn.getList()!=null)  {
                    for (SectorDTO dto:(List<SectorDTO>)genericColumn.getList())    {
                        if (dto.getId().equals(id))   {
                            return dto;
                        }
                    }
                }
            }
        }
        return null;
    }
    
    public LawFirmTypeDTO getLawFirmTypeDTO(int row, int column)  {
        try {
            ListBox listBox = (ListBox)getWidget(row, column);
            int selectedIndex = listBox.getSelectedIndex();
            String lawFirmType = listBox.getItemText(selectedIndex);
            return getLawFirmTypeDTO(lawFirmType);
        } catch (Exception e)   {
            return null;
        }
    }   
    
    @SuppressWarnings("unchecked")
    public LawFirmTypeDTO getLawFirmTypeDTO(String string)    {
        for (GenericColumn genericColumn:genericColumns.getColumns())   {
            if (genericColumn.getType()==(LawFirmTypeDTO.class)) {
                if (genericColumn.getList()!=null)  {
                    for (LawFirmTypeDTO dto:(List<LawFirmTypeDTO>)genericColumn.getList())    {
                        if (dto.getName().equals(string))   {
                            return dto;
                        }
                    }
                }
            }
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public LawFirmTypeDTO getLawFirmTypeDTO(Long id)    {
        for (GenericColumn genericColumn:genericColumns.getColumns())   {
            if (genericColumn.getType()==(LawFirmTypeDTO.class)) {
                if (genericColumn.getList()!=null)  {
                    for (LawFirmTypeDTO dto:(List<LawFirmTypeDTO>)genericColumn.getList())    {
                        if (dto.getId().equals(id))   {
                            return dto;
                        }
                    }
                }
            }
        }
        return null;
    }

    
}